import codesters
import random
from codesters.demo import Demo
from codesters import Text
demo = Demo()
stage_height = int(stage.get_stage_height())
stage_width = int(stage.get_stage_width())
def green_continue_action():
click_box.show()
click_text.show()
click_box.event_click(demo.return_paused_click())
demo.pause()
click_box.hide()
click_text.hide()
function_list = [
['1', 'stage', 'orange'], ['1', '.set_background(', 'white'], ['1', '"space"', 'green'], ['1', ')', 'white'],
['2', 'sprite', 'orange'], ['2', ' = codesters.Sprite(', 'white'], ['2', '"ufo"', 'green'], ['2', ')', 'white'],
['3', 'blank', ''],
['4', 'def hyper_speed():', 'white'],
['5', 'indent', 'function'], ['5', 'pass', 'white'],
['6', 'hyper_speed()', 'white']
]
def create_stage_code(input_list):
y = 225
spacing = 30
indent = 40
# Determine maximum line number
line_num = 1
for i in input_list:
if int(i[0]) > line_num:
line_num = int(i[0])
# Create code editor
top_padding = 10
bottom_padding = 10
code_bg = codesters.Rectangle(0, y, 500, spacing*line_num+top_padding+bottom_padding, "black")
code_bg.set_top(250)
left_guide = codesters.Rectangle(-215, 160, 2, spacing*line_num+top_padding+bottom_padding, "gray")
left_guide.set_top(250)
editor_list = [code_bg, left_guide]
# Add line numbers
line_num_list = []
line_num_y = y
for counter in range(line_num):
line_num = codesters.Text(counter+1, -235, line_num_y, "grey")
line_num.set_size(.8)
line_num_y -= spacing
line_num_list.append(line_num)
# The third input item is used to indicate the color
category_to_color = {
"white": "white",
"orange": "orange",
"green": "lightgreen",
"blue": "cornflowerblue",
"loop": "mediumpurple",
"conditional": "yellow",
"function": "green",
"black": "black",
"none": None,
"": None,
}
# Add code
code_list = []
previous_element = None
previous_line = 1
for entry in input_list:
code_line = int(entry[0])
code_string = entry[1]
code_color = entry[2].lower()
# Set color to preset options for easier inputting
code_color = category_to_color[code_color]
# Set left-align position
if previous_element == None or code_line != previous_line:
code_left_x = -205
else:
code_left_x = previous_element.get_right()
# Create the code element (indentation or text code)
if code_string == "blank":
element = codesters.Rectangle(code_left_x, y-spacing*(code_line-1), 1, 30, None)
elif code_string == "indent":
element = codesters.Rectangle(code_left_x, y-spacing*(code_line-1), 40, 30, code_color)
else:
element = codesters.Text(code_string, code_left_x, y-spacing*(code_line-1), code_color)
element.set_left(code_left_x) # Set it according to the location of the previous element
previous_element = element # Reset the previous element
previous_line = code_line # Reset the previous line number
code_list.append(element)
return [editor_list, line_num_list, code_list]
t = codesters.Teacher()
################################################
# Pass test code
# - set pass_required to True if pass is required
# - include tpass before t1 in the test list
pass_required = False
passes = t.find_text("pass")
num_pass_only = 0
for p in passes:
if p[1].lower().replace(' ','') == "pass":
num_pass_only += 1
# If there are no passes, skip the demo
if num_pass_only != 0:
guide = codesters.Sprite("person2")
guide.say("Let's see why using pass is helpful!")
stage.wait(1.5)
click_box = codesters.Rectangle(-203, -219, 125, 62.5, "green", "black")
click_text = codesters.Text("Continue", -197, -220, "white")
demo.add_hover_opacity_element(click_box)
green_continue_action()
guide.say("")
guide.move_down(185)
# Create stage code
code_editor = create_stage_code(function_list)
code_editor[2][-2].hide() # Hide pass for demo
line_num_list = code_editor[1]
guide.say("Look at the above code.")
stage.wait(1)
green_continue_action()
guide.say("Click on the highlighted part to learn more!")
highlight_box = codesters.Rectangle(-100, line_num_list[3].get_y(), 475, 25, "yellow")
highlight_box.set_left(-245)
highlight_box_x = highlight_box.get_x()
highlight_box.set_opacity(.3)
highlight_box.event_click(demo.return_paused_click())
demo.pause()
guide.say('This line defines a function that will run when we call it!')
stage.wait(2)
green_continue_action()
guide.say("Click on the highlighted part to learn more!")
highlight_box.glide_to(highlight_box_x, line_num_list[4].get_y())
highlight_box.event_click(demo.return_paused_click())
demo.pause()
guide.say("But there is no code indented inside the function yet.")
stage.wait(2)
guide.say("But there is no code indented inside the function yet.\n\nLet's see what happens. Click the Run button on the stage!")
run_circle = codesters.Circle(0, 0, 50, "lightgreen", "dimgray")
run_triangle = codesters.Triangle(2, 0, 15, "dimgray")
run_triangle.set_rotation(-90)
demo.add_hover_opacity_element(run_circle)
run_circle.event_click(demo.return_paused_click())
run_triangle.event_click(demo.return_paused_click())
demo.pause()
stage.remove_sprite(run_circle)
stage.remove_sprite(run_triangle)
highlight_box.go_to(highlight_box_x, line_num_list[0].get_y()+50)
guide.say("Click Continue to see the code run line by line.")
stage.wait(2)
green_continue_action()
highlight_box.glide_to(highlight_box_x, line_num_list[0].get_y())
stage.set_background("space")
guide.set_say_color("white")
guide.set_say_background("black", 1)
green_continue_action()
highlight_box.glide_to(highlight_box_x, line_num_list[1].get_y())
sprite = codesters.Sprite("ufo")
green_continue_action()
highlight_box.glide_to(highlight_box_x, line_num_list[2].get_y())
stage.wait(1)
highlight_box.glide_to(highlight_box_x, line_num_list[3].get_y())
green_continue_action()
highlight_box.glide_to(highlight_box_x, line_num_list[4].get_y())
guide.say("")
dimmer = codesters.Rectangle(0, 0, stage_width, stage_height, "black")
dimmer.set_opacity(.75)
error_message = demo.create_sprite_off_screen("bad_input_9bc", 0, -400, .75)
error_message.set_speed(20)
error_message.glide_to(0, 100)
ok_button = codesters.Rectangle(0, 40, 70, 50, "white")
ok_button.set_opacity(.01)
ok_button.event_click(demo.return_paused_click())
demo.pause()
guide.move_to_front()
guide.say('"bad input" on line 6? What\'s that about?')
stage.wait(2)
guide.say('"bad input" on line 6? What\'s that about?\n\nWhat is wrong with line 6?')
stage.wait(2)
click_box.move_to_front()
click_text.move_to_front()
green_continue_action()
guide.say('A "bad input" error is caused by missing or unexpected code.')
stage.wait(2)
guide.say('A "bad input" error is caused by missing or unexpected code.\n\nThis makes the program think the error is on the next line!')
stage.wait(2)
green_continue_action()
guide.say('We got this "bad input" error because the function is empty!')
stage.wait(2)
guide.say('We got this "bad input" error because the function is empty!\n\nClick OK!')
ok_button.event_click(demo.return_paused_click())
demo.pause()
dimmer.hide()
error_message.hide()
ok_button.hide()
guide.say("All loops, conditionals, and functions require at least one line of code.")
stage.wait(2)
guide.say("All loops, conditionals, and functions require at least one line of code.\n\nBut what if I don't know which code to add yet?")
stage.wait(2)
green_continue_action()
guide.say("This is where pass comes in handy!")
stage.wait(2)
guide.say("This is where pass comes in handy!\n\npass acts as placeholder code. It is code...but it does nothing!")
stage.wait(2)
green_continue_action()
guide.say("Click the highlight to add pass.")
highlight_box.event_click(demo.return_paused_click())
demo.pause()
guide.say("")
highlight_box.hide()
code_editor[2][-2].show()
guide.say("Let's see what it does!")
stage.wait(2)
guide.say("Let's see what it does!\n\nClick the Run button on the stage again!")
run_circle = codesters.Circle(0, 0, 50, "lightgreen", "dimgray")
run_triangle = codesters.Triangle(2, 0, 15, "dimgray")
run_triangle.set_rotation(-90)
demo.add_hover_opacity_element(run_circle)
run_circle.event_click(demo.return_paused_click())
run_triangle.event_click(demo.return_paused_click())
demo.pause()
guide.say("")
guide.set_say_color("black")
guide.set_say_background("#eee", .3)
stage.remove_sprite(run_circle)
stage.remove_sprite(run_triangle)
stage.set_background_color("#ECECEC")
stage.remove_sprite(sprite)
highlight_box.show()
highlight_box.go_to(highlight_box_x, line_num_list[0].get_y()+50)
guide.say("Click Continue to see the code run line by line.")
stage.wait(2)
green_continue_action()
highlight_box.glide_to(highlight_box_x, line_num_list[0].get_y())
stage.set_background("space")
guide.set_say_color("white")
guide.set_say_background("black", 1)
green_continue_action()
highlight_box.glide_to(highlight_box_x, line_num_list[1].get_y())
sprite = codesters.Sprite("ufo")
green_continue_action()
highlight_box.glide_to(highlight_box_x, line_num_list[2].get_y())
stage.wait(1)
highlight_box.glide_to(highlight_box_x, line_num_list[3].get_y())
green_continue_action()
highlight_box.glide_to(highlight_box_x, line_num_list[5].get_y())
green_continue_action()
highlight_box.glide_to(highlight_box_x, line_num_list[4].get_y())
guide.say("No error!")
green_continue_action()
guide.say("We have code in the conditional now, so there's no error!")
stage.wait(2)
guide.say("We have code in the conditional now, so there's no error!\n\nThis is a common use for pass.")
stage.wait(2)
green_continue_action()
guide.say("As soon as we add more code to the conditional, we can remove pass.")
stage.wait(2)
green_continue_action()
guide.say("Look at the code in the code editor.")
stage.wait(2)
guide.say("Look at the code in the code editor.\n\nRemove the pass and then Run the program again!")
demo.pause()
stage.set_background("space")
sprite = codesters.Sprite("ufo")
def hyper_speed():
pass
rand_x = random.randint(-225, 225)
rand_y = random.randint(-225, 225)
rand_speed = random.randint(5, 15)
sprite.set_speed(rand_speed)
sprite.glide_to(rand_x, rand_y)
hyper_speed()
hyper_speed()
hyper_speed()
tpass = TestObjective()
if not pass_required:
tpass.add_success(num_pass_only == 0, "Great job!")
tpass.add_success(num_pass_only > 0, "Great job! Feel free to delete pass statements now.")
tester = TestManager()
tester.add_test_list([tpass])
tester.run_tests()
if num_pass_only == 0:
tester.display_first_feedback()